home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (c) 1995-1999 NEC USA, Inc. All rights reserved. */
- /* */
- /* The redistribution, use and modification in source or binary forms of */
- /* this software is subject to the conditions set forth in the copyright */
- /* document ("Copyright") included with this distribution. */
-
- /*
- * $Id: sident.c,v 1.19.2.1.2.1 1999/02/03 22:35:44 steve Exp $
- */
-
- #include "socks5p.h"
- #include "threads.h"
- #include "daemon.h"
- #include "addr.h"
- #include "log.h"
-
- #ifdef HAVE_LIBIDENT
- #include <ident.h>
- #endif
-
- #ifndef IDENTTIMEOUT
- #define IDENTTIMEOUT 15
- #endif
-
- #ifdef HAVE_LIBIDENT
- static inline void filelock(S5IOHandle fd, int on) {
- #if defined(HAVE_FLOCK) && !defined(F_SETLKW)
- flock(fd, on?LOCK_EX:LOCK_UN);
- #else
- struct flock fl;
-
- fl.l_type = on?F_WRLCK:F_UNLCK;
- fl.l_whence = SEEK_SET;
- fl.l_start = 0;
- fl.l_len = 0;
-
- fcntl(fd, F_SETLKW, &fl);
- #endif
- }
-
- static inline S5IOHandle openidtfile(void) {
- int flags = O_RDWR | O_CREAT;
- S5IOHandle fd;
- struct stat sbuf;
- static char *myfile = NULL;
-
- if (!myfile) {
- MUTEX_LOCK(env_mutex);
- myfile = getenv("SOCKS5_IDENTFILE");
- myfile = myfile?strdup(myfile):strdup(SRVIDT_FILE);
- }
-
- if (lstat(myfile, &sbuf) || (S_ISLNK(sbuf.st_mode) && geteuid() != sbuf.st_uid)) flags |= O_EXCL;
- fd = open(myfile, flags, 0644);
- MUTEX_UNLOCK(env_mutex);
-
- if (fd == S5InvalidIOHandle) return fd;
- filelock(fd, 1);
- return fd;
- }
- #endif
-
- int IdentQuery(S5IOHandle fd, char *name) {
- #ifndef HAVE_LIBIDENT
- return 0;
- #else
- IDENT *idp;
- char *ev;
- int rval;
-
- IFTHREADED(static MUTEX_T idt_mutex = MUTEX_INITIALIZER;)
-
- IFTHREADED(MUTEX_SETUP(idt_mutex);)
-
- MUTEX_LOCK(env_mutex);
- ev = getenv("SOCKS5_NOIDENT");
- MUTEX_UNLOCK(env_mutex);
-
- if (ev) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: No Ident lookup (by request)");
- *name = '\0';
- return -1;
- }
-
- MUTEX_LOCK(idt_mutex);
-
- if ((idp = ident_lookup(fd, IDENTTIMEOUT)) == NULL) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Ident lookup failed: %m");
- *name = '\0';
- rval = -1;
- } else {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Ident lookup name was: %s", idp->identifier);
- strncpy(name, idp->identifier, MIN(strlen(idp->identifier)+1, S5_USERNAME_SIZE));
- if (strlen(idp->identifier)+1 > S5_USERNAME_SIZE) name[S5_USERNAME_SIZE-1] = '\0';
- ident_free(idp);
- rval = 0;
- }
-
- MUTEX_UNLOCK(idt_mutex);
- return rval;
- #endif
- }
-
- void InitIdentEntry(char *idtentry) {
- idtentry[0] = '\0';
- }
-
- void RemoveIdentEntry(char *idtentry) {
- #ifdef HAVE_LIBIDENT
- char *fbuf = NULL, *offset;
- struct stat sb;
- S5IOHandle fd;
-
- if (*idtentry == '\0') return;
- if ((fd = openidtfile()) == S5InvalidIOHandle) return;
-
- if (fstat(fd, &sb) < 0) goto end;
- if (!(fbuf = (char *)malloc((sb.st_size+1)*sizeof(char)))) goto end;
- if (READFILE(fd, fbuf, sb.st_size) < 0) goto end;
- fbuf[sb.st_size] = '\0';
-
- if ((offset = strstr(fbuf, idtentry)) == NULL) goto end;
- lseek(fd, offset-fbuf, 0);
- WRITEFILE(fd, offset + strlen(idtentry), (sb.st_size - (offset-fbuf) - strlen(idtentry)));
-
- /* XXX For now, if you don't have ftruncated, you loose. BSD & SVR4 */
- /* both do, so there shouldn't be too many losers. */
- ftruncate(fd, sb.st_size - strlen(idtentry));
-
- end:
- if (fbuf) free(fbuf);
- if (fd >= 0) close(fd);
- #endif
- }
-
- void MakeIdentEntry(S5IOHandle in, S5IOHandle out, S5LinkInfo *linkinfo, char *idtentry) {
- #ifdef HAVE_LIBIDENT
- char *user, identname[S5_USERNAME_SIZE];
- S5NetAddr tmp, *dst;
- S5IOHandle fd;
- int len;
-
- if (*idtentry != '\0') {
- RemoveIdentEntry(idtentry);
- }
-
- if (linkinfo->peerAuth == AUTH_NONE || IdentQuery(in, identname) < 0) {
- user = linkinfo->srcUser;
- } else {
- user = identname;
- }
-
- if (!strlen(user)) {
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Not recording ident info for empty username");
- return;
- }
-
- if (linkinfo->nextVersion) {
- dst = &linkinfo->sckAddr;
- } else {
- dst = &linkinfo->dstAddr;
- }
-
- len = sizeof(S5NetAddr);
- memset(&tmp, 0, len);
- getsockname(out, &tmp.sa, &len);
-
- sprintf(idtentry, "%s,%d,", ADDRANDPORT(dst));
- sprintf(idtentry+strlen(idtentry), "%s,%d,", ADDRANDPORT(&tmp));
- sprintf(idtentry+strlen(idtentry), "%s\n", user);
-
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Recording ident info for user: %s", user);
-
- if ((fd = openidtfile()) == S5InvalidIOHandle) return;
- WRITEFILE(fd, idtentry, strlen(idtentry));
- close(fd);
-
- S5LogUpdate(S5LogDefaultHandle, S5_LOG_DEBUG(10), 0, "Ident: Ident info recorded");
- #endif
- }
-
-